package com.lakeworks.framework.web.service;

import com.alibaba.fastjson.JSONObject;
import com.lakeworks.common.core.domain.AjaxResult;
import com.lakeworks.common.core.domain.entity.SysRole;
import com.lakeworks.common.core.domain.entity.SysUser;
import com.lakeworks.domain.SysWechatUser;
import com.lakeworks.domain.vo.LoginVO;
import com.lakeworks.domain.vo.WechatUserInfo;
import com.lakeworks.service.ISysUserService;
import com.lakeworks.service.ISysWechatUserService;
import com.lakeworks.service.IWechatOAuth2Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.util.ArrayList;

import static com.lakeworks.common.constant.Constants.TOKEN;
import static com.lakeworks.common.core.domain.AjaxResult.success;
import static com.lakeworks.common.utils.bean.DeepCopyUtil.transform;

/**
 * @Author: Auxps
 * @Date: 2023/2/20
 * Description:
 */
@Service
public class WechatOAuth2ServiceImpl implements IWechatOAuth2Service {

    private static final String LOGINURL = "https://login.haishenxiyi.net/user/";

    private static final Logger log = LoggerFactory.getLogger(WechatOAuth2ServiceImpl.class);

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ISysWechatUserService sysWechatUserService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private SysLoginService sysLoginService;

    @Autowired
    private TokenService tokenService;

    @Override
    public JSONObject userInfo(String code) {

        URI uri = UriComponentsBuilder
                .fromUriString(LOGINURL)
                .path(code)
                .build()
                .toUri();
        try {
            ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(uri, JSONObject.class);
            log.info("微信登录，获取用户信息，response：[{}]", responseEntity);
            return responseEntity.getBody();
        } catch (HttpStatusCodeException e) {
            log.error("Response status: [{}]", e.getStatusCode());
            e.getResponseHeaders().forEach((key, values) -> log.error("Response header [{}]: {}", key, values));
            log.error("Response body: [{}]", e.getResponseBodyAsString());
            throw new RuntimeException("获取用户信息失败");
        }
    }

    @Override
    public String token(HttpServletRequest request) {
        String token = tokenService.renewToken(request);
        log.info("刷新token：[{}]",token);
        return token;
    }

    /**
     * 登录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult login(WechatUserInfo wechatUserInfo) {
        SysWechatUser wechatUser = sysWechatUserService.selectByOpenId(wechatUserInfo.getOpenid());
        SysUser sysUser = null;
        if (wechatUser == null) {
            sysUser = saveSysUser(wechatUserInfo);
            wechatUser = saveWechatUser(wechatUserInfo, sysUser.getUserId());
        } else {
            sysUser = sysUserService.selectUserByOpenId(wechatUserInfo.getOpenid());
            if (!wechatUserInfo.getNickname().equals(sysUser.getNickName()) || !wechatUserInfo.getHeadimgurl().equals(sysUser.getAvatar())) {
                sysUserService.updateNickAvatarByUserId(wechatUser.getUserId(), wechatUserInfo.getNickname(), wechatUserInfo.getHeadimgurl());
                sysUser.setNickName(wechatUserInfo.getNickname());
                sysUser.setAvatar(wechatUserInfo.getHeadimgurl());
            }
        }
        return success(transform(sysUser, LoginVO.class).setRoleKeyArray(sysUser.getRoles().stream().map(SysRole::getRoleKey).toArray(String[]::new)))
                .put(TOKEN, sysLoginService.wechatLogin(sysUser,wechatUserInfo.getOpenid()));
    }

    public SysUser saveSysUser(WechatUserInfo wechatUserInfo) {
        SysUser sysUser = new SysUser();

        sysUser.setNickName(wechatUserInfo.getNickname());
        sysUser.setAvatar(wechatUserInfo.getHeadimgurl());
        sysUser.setSex(String.valueOf(wechatUserInfo.getSex()));

        sysUserService.insertUser(sysUser);
        sysUser.setRoles(new ArrayList<>());
        return sysUser;
    }

    public SysWechatUser saveWechatUser(WechatUserInfo wechatUserInfo, Long sysUserId) {
        SysWechatUser sysWechatUser = transform(wechatUserInfo, SysWechatUser.class).setUserId(sysUserId);
        sysWechatUserService.insertSysWechatUser(sysWechatUser);

        return sysWechatUser;
    }

}
